package LinkedList;//给你一个长度为 n 的链表，每个节点包含一个额外增加的随机指针 random ，该指针可以指向链表中的任何节点或空节点。
//
// 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成，其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 
//指针也都应指向复制链表中的新节点，并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。 
//
// 例如，如果原链表中有 X 和 Y 两个节点，其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ，同样有 x.random 
//--> y 。 
//
// 返回复制链表的头节点。 
//
// 用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示： 
//
// 
// val：一个表示 Node.val 的整数。 
// random_index：随机指针指向的节点索引（范围从 0 到 n-1）；如果不指向任何节点，则为 null 。 
// 
//
// 你的代码 只 接受原链表的头节点 head 作为传入参数。 
//
// 
//
// 示例 1： 
//
// 
//
// 
//输入：head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
//输出：[[7,null],[13,0],[11,4],[10,2],[1,0]]
// 
//
// 示例 2： 
//
// 
//
// 
//输入：head = [[1,1],[2,1]]
//输出：[[1,1],[2,1]]
// 
//
// 示例 3： 
//
// 
//
// 
//输入：head = [[3,null],[3,0],[3,null]]
//输出：[[3,null],[3,0],[3,null]]
// 
//
// 
//
// 提示： 
//
// 
// 0 <= n <= 1000 
// -10⁴ <= Node.val <= 10⁴ 
// Node.random 为 null 或指向链表中的节点。 
// 
// Related Topics 哈希表 链表 👍 843 👎 0


//leetcode submit region begin(Prohibit modification and deletion)
/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/

class copyRandomList {
    public Node copyRandomList(Node head) {

        //特例
        if(head == null){
            return null;
        }
        Node curHead = head;
        //1.对原始主链进行复制
        while(curHead!=null){
            Node curNext = curHead.next; //保存下一节点
            Node curCopy = new Node(curHead.val); //复制当前节点
            curCopy.next = curNext;  //复制节点的后继指向原节点后继
            curHead.next = curCopy;  //当前节点后继指向复制的节点

            curHead = curNext; //当前节点移动到原第二个几点
        }

        //2.重新遍历链表，复制原结点的随机指针给新结点，如A1.random=A.random.next;
        Node curNode = head;
        while(curNode!=null){
            Node copynode = curNode.next;  //指向当前节点的复制节点
            //复制节点的随机指针，指向原节点的随机指针指向的位置的next(复制节点)
            copynode.random = curNode.random==null ? null : curNode.random.next;
            curNode = copynode.next;  //移动到下一个原指针
        }
        //3.拆分链表，将链表拆分为为原链表和复制后的链表
        curHead = head;  //原链表头
        Node copyHead = curHead.next;  //复制链表的头
        while(curHead!=null){
            Node curCopy = curHead.next;  //当前复制节点
            curHead.next = curCopy.next;  //原来的跨一个再重新连接
            curCopy.next = curHead.next == null ? null : curHead.next.next ;

            curHead = curHead.next;
        }
        return copyHead;
    }
}
//leetcode submit region end(Prohibit modification and deletion)
